package com.model;

import java.util.LinkedList;
import java.util.List;

import org.omg.CosNaming.IstringHelper;

import com.strategies.IStrategy;

public class Hand {

	private List<Card> hand = new LinkedList<Card>();
	private boolean isSoft = false;
	private IStrategy strategy;
	protected static final double MINIMUM_BET = 6;
	private double bet = MINIMUM_BET;
	private boolean canDouble = true;
	
	public Hand(IStrategy strategy, double bet, boolean canDouble) {
		this.canDouble = canDouble;
		this.strategy = strategy;
		this.bet = bet;
	}
	public Hand(IStrategy strategy, double bet) {
		this(strategy, MINIMUM_BET, true); 
	}
	
	public Hand(IStrategy strategy) {
		this(strategy, MINIMUM_BET);
	}

	public List<Card> getHand() {
		return hand;
	}

	public void setHand(List<Card> hand) {
		this.hand = hand;
	}
	
	public void clearHand() {
		this.hand.clear();
		isSoft = false;
	}
	
	public Card getFirstCard() {
		return this.hand.get(0);
	}
	
	public Card getSecondCard() {
		return this.hand.get(1);
	}
	
	public void addCard(Card card) {
		this.hand.add(card);
	}
	
	public int getTotalHandValue() {
        //returns the numeric score of the hand
        int total = 0;
        boolean aceFound = false;        //set if an ace has been counted as 11 instead of 1 
		for (Card card : hand){
            total += card.getValue();
            
            if ((total + 10 <= 21) && (card.rank() == Rank.ACE)){
                    total += 10;
                    aceFound = true;
            }
            if (total > 21 && aceFound){
                    total -= 10;
                    aceFound = false;
            }
		}
		isSoft = aceFound;
		return total;
	}
	
	public boolean hasBusted() {
		if (getTotalHandValue() > 21 ) {
			return true;
		}
		return false;
	}
	
	public boolean hasBlackJack() {
		if (getHand().size() == 2 && getTotalHandValue() == 21) {
			return true;
		}
		return false;
	}
	
	public boolean isInitialSoftHand() {
		if (getHand().size() == 2 && (getHand().get(0).rank().equals(Rank.ACE) || getHand().get(1).rank().equals(Rank.ACE))) {
			return true;
		}
		return false;
	}

	public int size() {
		return hand.size();
	}

	public boolean isSoft() {
		return isSoft;
	}
	
	public boolean shouldSplit(Card dealerCard) {
		return strategy.shouldSplit(this, dealerCard);
	}
	
	public boolean shouldDouble(Card dealerCard) {
		return strategy.shouldDouble(this, dealerCard);
	}
	
	public boolean shouldHit(Card dealerCard) {
		return strategy.shouldHit(this, dealerCard);
	}
	
	public String toString() {
		return hand.toString();
	}

	public double getBet() {
		return bet;
	}

	public void setBet(double bet) {
		this.bet = bet;
	}

	public boolean canDouble() {
		return canDouble;
	}

	public void setCanDouble(boolean canDouble) {
		this.canDouble = canDouble;
	}

}
